package com.jahe.learn.netty4.websocket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.buffer.UnpooledDirectByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * websocket client handler
 * @author: jahe.lai
 * @create: 2019-12-27 15:02
 */
public class WSClientHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    protected static Logger logger = LoggerFactory.getLogger(WSClientHandler.class);


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
        Channel channel = ctx.channel();

        if (msg instanceof TextWebSocketFrame) {
            TextWebSocketFrame textFrame = (TextWebSocketFrame)msg;
            //this.listener.onMessage(textFrame.text());
            logger.info("TextWebSocketFrame=" + textFrame.text());

        } else if (msg instanceof BinaryWebSocketFrame) {
            BinaryWebSocketFrame binFrame = (BinaryWebSocketFrame)msg;
            logger.info("BinaryWebSocketFrame received.");

        } else if (msg instanceof PongWebSocketFrame) {
            PongWebSocketFrame pong = (PongWebSocketFrame) msg;
            // PooledUnsafeDirectByteBuf
            ByteBuf byteBuf = pong.content();
            ByteBuf mybb = Unpooled.copiedBuffer(byteBuf);
            String content = new String(mybb.array());
            logger.info("pongMsg={}", content);

            if("TIMEOUT".equals(content)) {
                ctx.channel().writeAndFlush(new PingWebSocketFrame(Unpooled.copiedBuffer("TIMEOUT-PING".getBytes())));
            }


        } else if (msg instanceof CloseWebSocketFrame) {
            CloseWebSocketFrame frame1 = (CloseWebSocketFrame)msg;
            logger.info("CloseWebSocketFrame status_code=" + frame1.statusCode() + ", text=" + frame1.reasonText());
            //this.listener.onClose(((CloseWebSocketFrame)frame).statusCode(), ((CloseWebSocketFrame)frame).reasonText());
            channel.close();
        } else {
            logger.info("handler= "+msg.getClass());
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        // 连接断开时，自动重新连接
        logger.warn("channelInactive, invoke connection.");
        WebSocketClient.connection();

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }
}
